04 DAC实验
DAC输出电压实验 DAC波形实验 扬声器实验
up的视频讲解: https://space.bilibili.com/1455872040
up视频里的实验代码: 👣DAC实验代码
DAC驱动文件: DAC驱动代码
播放生日快乐: 🥳DAC驱动扬声器播放生日快乐
注意

如果盒子里面有这个小卡片的话 代表着up把SCL和SDA的丝印画反了 大家可以按照小卡片上的来
1 📢 蜂鸣器-DAC电压输出实验
1.1 实验连接

1.2 实验原理
- F103C8T6没有片内DAC,不能在本芯片上照着其他型号开启片内DAC
- 通过IIC通信 设置外置DAC的输出值
1.3 CubeMX配置
课程DAC驱动使用hi2c2,配置I2C2,配置Fast Mode快速模式,在从设备特性中配置 禁用时钟拉伸
警用时钟拉伸
这个应该是从设备才需要配置的,但是F103C8T6存在一些设计缺陷所有需要配置一下


1.4 实验代码
全局
#include "dac.h"
main()
DAC_SetDigital(0.7/3.3*4096);
while(1)
2 〰️ DAC波形发生实验
2.1 实验连接

2.2 实验原理
- 通过定时器触发 控制外置DAC输出正弦波形
- sin函数里面的参数 是正弦函数的相位 使用的是弧度制
- (0°
360°)角度制 / 360 = (02π)弧度制 / 2π
2.3 CubeMX配置
I2C2保持上一实验配置。TIM2选择Internal Clock并开启更新中断;假设TIM2时钟72 MHz,可先设PSC=71、ARR=999,得到1000次/秒更新。



2.4 实验代码
全局
#include "dac.h"
#include "math.h"
#define PI 3.1415926535
uint8_t flag = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
flag = 1;
}
}
main()
HAL_TIM_Base_Start_IT(&htim2);
float idx = 0;
float step = 3.6;
while(1)里面
if(flag == 1)
{
float phase = 2.0f*PI*(idx/360.0f);
uint16_t dac_val = 4095.0f*((sinf(phase)+1.0f)/2.0f);
DAC_SetDigital(dac_val);
idx += step;
flag = 0;
}
✅输出频率为什么不对
先输出固定码0、1024、2048,测量电压,再输出慢速查表波形。一个周期N个点、每秒更新Fs次,理想频率为Fs/N。
本驱动一次快速写入含地址和两个数据字节,至少27个SCL时钟,另有起止及软件开销。100 kHz时仅总线传输就约270 μs,不能承诺8 kHz更新;提高到400 kHz也仍需测量完整事务耗时。
flag只表示有事件,多个定时器事件可能合并。此处适合低速波形演示,连续音频输出应设计缓冲和非阻塞传输。观察到台阶波形时,还要区分采样点太少与模拟重建滤波不足。